﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ApkInstaller.Util;
using ICSharpCode.SharpZipLib.Zip;

namespace ApkInstaller
{
    public partial class FrmMain : Form
    {
        private string _apkFile = null;
        private bool _isInstalling = false;
        private ApkInfo _apkInfo = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public FrmMain()
        {
            InitializeComponent();
            this.pictureBoxApkIcon.AllowDrop = true;
            this.visualStyler1.LoadVisualStyle(@"Sustenance (Blue).vssf");
            string userName = ConfigurationManager.AppSettings["userName"];
            this.Text += " v" + Application.ProductVersion + " (" + userName + ")";
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        
        /// <summary>
        /// 点击picturebox安装apk
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBoxApkIcon_MouseClick(object sender, MouseEventArgs e)
        {
            if (_isInstalling)
                return;

            if (e.Button == MouseButtons.Left)
            {
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Multiselect = false;
                ofd.Filter = "apk文件(*.apk)|*.apk";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    _apkFile = ofd.FileName;
                    ReadApkInfo(_apkFile);
                }
            }
            else if(e.Button == MouseButtons.Right)
            {
                if (_apkInfo != null)
                {
                    ContextMenuStrip cms = new ContextMenuStrip();
                    cms.Items.Add("保存图标", null, (o, args) =>
                    {
                        SaveFileDialog dialog = new SaveFileDialog();
                        dialog.Title = "保存图标";
                        dialog.Filter = "*.png|*.png";
                        dialog.FilterIndex = 1;
                        if (dialog.ShowDialog() == DialogResult.OK)
                        {
                            string iconFile = _apkInfo.iconFileName[0];
                            byte[] iconBytes = GetFileFromZip(_apkFile, iconFile);
                            System.IO.File.WriteAllBytes(dialog.FileName, iconBytes);
                        }
                    });
                    cms.Show(this.pictureBoxApkIcon,e.Location);
                }
            }
        }

        /// <summary>
        /// 拖拽文件安装apk-dragenter
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBoxApkIcon_DragEnter(object sender, DragEventArgs e)
        {
            if (_isInstalling)
                return;

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.All;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }

        /// <summary>
        /// 拖拽文件安装apk-dragdrop
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBoxApkIcon_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = e.Data.GetData(DataFormats.FileDrop, false) as string[];

            _apkFile = files[0];
            ReadApkInfo(_apkFile);
        }

        /// <summary>
        /// 读取apk信息
        /// </summary>
        /// <param name="apkFile"></param>
        private void ReadApkInfo(string apkFile)
        {
            byte[] manifestBytes = null;
            byte[] resourcesBytes = null;

            manifestBytes = GetFileFromZip(apkFile, "AndroidManifest.xml");
            resourcesBytes = GetFileFromZip(apkFile, "resources.arsc");
            ApkReader reader = new ApkReader();
            _apkInfo = reader.extractInfo(manifestBytes, resourcesBytes);
            this.textBoxApkName.Text = _apkInfo.label;
            this.textBoxApkPacketName.Text = _apkInfo.packageName;
            this.textBoxApkVersion.Text = _apkInfo.versionName;
            this.textBoxApkMinSdkVersion.Text = _apkInfo.minSdkVersion;
            this.textBoxApkTargetSdkVersion.Text = _apkInfo.targetSdkVersion;
            this.textBoxApkActiveActivity.Text = _apkInfo.activeActivity;
            string iconFile = _apkInfo.iconFileName[0];
            byte[] iconBytes = GetFileFromZip(apkFile, iconFile);
            this.pictureBoxApkIcon.BackgroundImage = Image.FromStream(new MemoryStream(iconBytes));
        }

        /// <summary>
        /// 获取zip中的文件信息
        /// </summary>
        /// <param name="inputFile"></param>
        /// <param name="outputFile"></param>
        /// <returns></returns>
        private byte[] GetFileFromZip(string inputFile, string outputFile)
        {
            using (FileStream fs = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
            {
                using (ICSharpCode.SharpZipLib.Zip.ZipFile zipFile = new ICSharpCode.SharpZipLib.Zip.ZipFile(fs))
                {
                    IEnumerator enumerator = zipFile.GetEnumerator();
                    ZipEntry entry = null;
                    while (enumerator.MoveNext())
                    {
                        entry = enumerator.Current as ZipEntry;
                        if (entry.Name.Equals(outputFile, StringComparison.CurrentCultureIgnoreCase))
                        {
                            using (Stream stream = zipFile.GetInputStream(entry))
                            {
                                byte[] buffer = new byte[entry.Size];
                                stream.Read(buffer, 0, buffer.Length);

                                return buffer;
                            }
                        }
                    }
                }
            }

            return null;
        }

        /// <summary>
        /// 设置控件Text属性
        /// </summary>
        /// <param name="control"></param>
        /// <param name="text"></param>
        private void SetControlText(Control control, string text)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<Control, string>(SetControlText), control, text);
                return;
            }
            control.Text = text;
        }

        /// <summary>
        /// 设置控件Enabled属性
        /// </summary>
        /// <param name="control"></param>
        /// <param name="enabled"></param>
        private void SetControlEnabled(Control control, bool enabled)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<Control, bool>(SetControlEnabled), control, enabled);
                return;
            }
            control.Enabled = enabled;
        }

        /// <summary>
        /// 安装APK
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonInstall_Click(object sender, EventArgs e)
        {
            if (_isInstalling)
                return;

            if (_apkFile == null)
            {
                MessageBox.Show("请先选择apk文件！");
                return;
            }
            SetStatusInfo("检测其他adb进程...");
            CheckOtherAdbProcess();
            SetStatusInfo("安装中...");
            //SetControlText(this.buttonInstall, "安装中...");
            SetControlEnabled(this.buttonInstall, false);
            RunProgress(true);

            new Thread(() =>
            {
                try
                {
                    _isInstalling = true;
                    string str = string.Empty;
                    RunAdb("install " + _apkFile, out str);
                    if (str.Contains("INSTALL_FAILED_ALREADY_EXISTS"))
                    {
                        SetStatusInfo("卸载中...");
                        //SetControlText(this.buttonInstall, "卸载中...");
                        RunAdb("uninstall " + _apkInfo.packageName, out str);

                        SetStatusInfo("安装中...");
                        //SetControlText(this.buttonInstall, "安装中...");
                        RunAdb("install " + _apkFile, out str);
                    }
                    // 启动apk
                    try
                    {
                        SetStatusInfo("启动APP中...");
                        string str2;
                        RunAdb(string.Format("shell am start -n {0}/{1}", _apkInfo.packageName,_apkInfo.activeActivity), out str2);
                    }
                    catch
                    {
                    }

                    if (str.Contains("INSTALL_FAILED_ALREADY_EXISTS"))
                    {
                        SetStatusInfo("安装失败！", Color.Red);
                        MessageBox.Show("安装失败,设备上已安装该apk！");
                    }
                    else if (str.Contains("unauthorized"))
                    {
                        SetStatusInfo("安装失败！", Color.Red);
                        MessageBox.Show("安装失败,请在设备上授权USB调试！");
                    }
                    else if (!str.Contains("Failure") && !str.Contains("failed"))
                    {
                        SetStatusInfo("安装成功！", Color.Green);
                        //MessageBox.Show("安装成功！");
                    }
                    else
                    {
                        SetStatusInfo("安装失败！", Color.Red);
                        MessageBox.Show("安装失败," + str);
                    }
                }
                catch (Exception ex)
                {

                }
                _isInstalling = false;
                SetControlText(this.buttonInstall, "安装");
                SetControlEnabled(this.buttonInstall, true);
                RunProgress(false);

            }) { IsBackground = true }.Start();
        }

        private void SetStatusInfo(string info)
        {
            SetStatusInfo(info, Color.Black);
        }

        private void SetStatusInfo(string info, Color color)
        {
            this.label7.Text = info;
            this.label7.ForeColor = color;
        }

        private void RunProgress(bool run)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<bool>(RunProgress), run);
                return;
            }
            if (run)
            {
                this.progressBarEx1.StartAnimation();
            }
            else
            {
                this.progressBarEx1.StopAnimation();
            }
        }

        private void RunAdb(string args, out string str)
        {
            string adbFile = Application.StartupPath + "\\bin\\adb.exe";
            Process p = new Process();
            p.StartInfo.FileName = adbFile;
            p.StartInfo.Arguments = args;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.Start();
            string info = string.Empty;
            string err = string.Empty;
            p.ErrorDataReceived += (sender, e) =>
            {
                info += e.Data;
            };
            p.OutputDataReceived += (sender, e) =>
            {
                err += e.Data;
            };
            p.BeginErrorReadLine();
            p.BeginOutputReadLine();
            p.WaitForExit(10*1000);

            //Console.WriteLine(info);
            //Console.WriteLine(err);
            str = info + "\r\n" + err;
        }

        /// <summary>
        /// 查看权限
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonViewPermission_Click(object sender, EventArgs e)
        {
            if (_apkInfo == null)
            {
                MessageBox.Show("请先选择apk文件！");
                return;
            }

            var frm = new FrmViewPermissions(_apkInfo);
            frm.Owner = this;
            frm.Show();
        }

        /// <summary>
        /// 检测其他adb进程
        /// </summary>
        private void CheckOtherAdbProcess()
        {
            KillProcess("360MobileMgr.exe");
        }

        /// <summary>
        /// 结束进程
        /// </summary>
        /// <param name="name">如：360MobileMgr.exe</param>
        private void KillProcess(string name)
        {
            Process p = new Process();
            p.StartInfo.FileName = "taskkill.exe";
            p.StartInfo.Arguments = "/f /im " + name;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            try
            {
                p.Start();
            }
            catch (Exception ex)
            {
            }
        }
    }
}
